[LOADER] More sanity checks when parsing Elf images to avoid
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 21 May 2006 19:15:58 +0000 (20:15 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 21 May 2006 19:15:58 +0000 (20:15 +0100)
out-of-bounds array accesses when loading the image.
Signed-off-by: Keir Fraser <keir@xensource.com>
tools/libxc/xc_load_elf.c
xen/common/elf.c

index 1cb821b8b93495bce4fe00f5ed168b63105423c8..0c60f683cd9948f2266aaf28e04c0b79bf5cf3bf 100644 (file)
@@ -158,12 +158,17 @@ static int parseelfimage(const char *image,
     elf_pa_off_defined = (p != NULL);
     elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
 
+    if ( elf_pa_off_defined && !virt_base_defined )
+        goto bad_image;
+
     for ( h = 0; h < ehdr->e_phnum; h++ )
     {
         phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
         if ( !is_loadable_phdr(phdr) )
             continue;
         vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+        if ( (vaddr + phdr->p_memsz) < vaddr )
+            goto bad_image;
         if ( vaddr < kernstart )
             kernstart = vaddr;
         if ( (vaddr + phdr->p_memsz) > kernend )
@@ -184,11 +189,9 @@ static int parseelfimage(const char *image,
 
     if ( (kernstart > kernend) ||
          (dsi->v_kernentry < kernstart) ||
-         (dsi->v_kernentry > kernend) )
-    {
-        ERROR("Malformed ELF image.");
-        return -EINVAL;
-    }
+         (dsi->v_kernentry > kernend) ||
+         (dsi->v_start > kernstart) )
+        goto bad_image;
 
     if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
         dsi->load_symtab = 1;
@@ -200,6 +203,10 @@ static int parseelfimage(const char *image,
     loadelfsymtab(image, 0, 0, NULL, dsi);
 
     return 0;
+
+ bad_image:
+    ERROR("Malformed ELF image.");
+    return -EINVAL;
 }
 
 static int
index 6fad5c5437dabba348c36d216dd99c742d34c9ca..b5a18f317a0669690e6f842cf6574f84e517ad2f 100644 (file)
@@ -94,12 +94,17 @@ int parseelfimage(struct domain_setup_info *dsi)
     elf_pa_off_defined = (p != NULL);
     elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
 
+    if ( elf_pa_off_defined && !virt_base_defined )
+        goto bad_image;
+
     for ( h = 0; h < ehdr->e_phnum; h++ )
     {
         phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
         if ( !is_loadable_phdr(phdr) )
             continue;
         vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+        if ( (vaddr + phdr->p_memsz) < vaddr )
+            goto bad_image;
         if ( vaddr < kernstart )
             kernstart = vaddr;
         if ( (vaddr + phdr->p_memsz) > kernend )
@@ -120,11 +125,9 @@ int parseelfimage(struct domain_setup_info *dsi)
 
     if ( (kernstart > kernend) || 
          (dsi->v_kernentry < kernstart) ||
-         (dsi->v_kernentry > kernend) )
-    {
-        printk("Malformed ELF image.\n");
-        return -EINVAL;
-    }
+         (dsi->v_kernentry > kernend) ||
+         (dsi->v_start > kernstart) )
+        goto bad_image;
 
     if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
             dsi->load_symtab = 1;
@@ -136,6 +139,10 @@ int parseelfimage(struct domain_setup_info *dsi)
     loadelfsymtab(dsi, 0);
 
     return 0;
+
+ bad_image:
+    printk("Malformed ELF image.\n");
+    return -EINVAL;
 }
 
 int loadelfimage(struct domain_setup_info *dsi)